/*
 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: CC0-1.0
 */

#include "c3_main.h"
#include "socket.h"
#include "gatts_table_creat_demo.h" //ble蓝牙
#include "wifi.h"                   //WIFI
#include "zhongduan.h"              //中断
#include "zhi_xing.h"

static const char *TAG = "c3_main: ";
#define led_pin GPIO_NUM_2
#define led_deng_dai GPIO_NUM_20

// 多线程,定义消息缓冲区句柄
MessageBufferHandle_t zhuanFanP; // 所有接收到的消息转发
QueueHandle_t ledPwmLD;       // 中断启用与关闭消息队列

//bool wifi_switch_BQ = false; // 是否运行WIFI

/*LEDPWM初始化*/
void led_pwm_Config()
{
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_0,
        .duty_resolution = LEDC_TIMER_13_BIT, // LEDC PWM 占空比分辨率为 13 位
        .freq_hz = (5000),                    // Set output frequency at 5 kHz
        .clk_cfg = LEDC_APB_CLK               // LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_0,
        .timer_sel = LEDC_TIMER_0,
        .intr_type = LEDC_INTR_DISABLE,
        .gpio_num = led_deng_dai,
        .duty = 0, // Set duty to 0%
        .hpoint = 0};
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
/*发送LEDPWM方波*/
void ledPwmTianYao(float zhanKongBi) // zhanKongBi = 0.1到1之间
{
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8190 * zhanKongBi)); // 负占空比，负值为50/256=19.5%; 0-8190
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
}

// GPIO初始化
void gpioInit(void)
{
    gpio_reset_pin(led_pin); // 清除 GPIO 默认的状态
    gpio_reset_pin(led_deng_dai);
    // gpio_pad_select_gpio(GPIO_NUM_22);

    gpio_set_direction(led_pin, GPIO_MODE_OUTPUT);            // GPIO 输出模式
    gpio_set_direction(led_deng_dai, GPIO_MODE_INPUT_OUTPUT); // GPIO 输出模式
}
void xin_pian_xin_xi() // 打印芯片信息
{
    /* *******************打印芯片信息*********** */
    esp_chip_info_t chip_info;
    uint32_t flash_size;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
           CONFIG_IDF_TARGET,
           chip_info.cores,
           (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
           (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
           (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
           (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");

    unsigned major_rev = chip_info.revision / 100;
    unsigned minor_rev = chip_info.revision % 100;
    printf("silicon revision v%d.%d, ", major_rev, minor_rev);
    if (esp_flash_get_size(NULL, &flash_size) != ESP_OK)
    {
        printf("Get flash size failed");
        return;
    }

    printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
           (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

    printf("Minimum free heap size: %" PRIu32 " bytes\r\n", esp_get_minimum_free_heap_size());
    ESP_LOGI(TAG, "芯片信息打印完毕\r\n");
    /***************** 打印芯片信息******** */
}

bool jian_la_huan_chong_qu() // 以动态分配内存的方式建立消息缓冲区
{
    // 以动态分配内存的方式建立消息缓冲区
    // pwmP = xMessageBufferCreate(PWNP_XIAO_XI);
    // kongZhiP = xMessageBufferCreate(KONGZHIP_XIAO_XI);
    zhuanFanP = xMessageBufferCreate(ZHUAN_FA_XIAO_XI);
    ledPwmLD = xQueueCreate(10, sizeof(uint16_t)); // 传递uint16_t类型消息
    if (zhuanFanP == NULL || ledPwmLD == NULL)
    {
        ESP_LOGI(TAG, "huan chong qu jian li shi bai 001\n");
        return false;
    }
    else
    {
        ESP_LOGD(TAG, "huan chong qu jian li cheng gong 001\n");
        return true;
    }
}

void shi_jian_SNTP_1()
{
    esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
    esp_netif_sntp_init(&config);
}
void shi_jian_SNTP_2()
{
    if (esp_netif_sntp_sync_wait(pdMS_TO_TICKS(10000)) != ESP_OK)
    {
        printf("10s超时内更新系统时间失败\n");
    }
}

void app_main(void)
{
    #if TIAO_SHI == 0
    esp_log_level_set("*", ESP_LOG_NONE);//设置日志输出级别(当前关闭)
    #endif
    xin_pian_xin_xi();       // 打印芯片信息
    gpioInit();              // GPIO初始化
    led_pwm_Config();        // pwm初始化
    ledPwmTianYao(0);       //pwm关闭输出
    jian_la_huan_chong_qu(); // 建立缓冲区
    nvs_init();              // 初始化NVS功能 
    vTaskDelay(100 / portTICK_PERIOD_MS);
    queue_init();

    /*xTaskCreate 建立新任务(线程)*/
    xTaskCreate(xi_tong_kong_zhi, "xi_tong_kong_zhi", 1024 * 3, NULL, 11, NULL);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    xTaskCreate(led_pwm,   // 指向任务入口函数的指针。任务必须实现为永不返回（即连续循环），或者应该使用 vTaskDelete 函数终止
                "led_pwm", // 任务的描述性名称。这主要是为了*方便调试。configMAX_TASK_NAME_LEN 定义的最大长度 - 默认 * 为 16。
                1024 * 2,  // 任务堆栈的大小指定为 * 字节数。请注意，这与普通 FreeRTOS 不同。
                NULL,      // 将用作正在创建的任务的参数的指针。
                10,        // 任务应运行的优先级。
                NULL);     // 用于传回一个句柄，通过该句柄可以引用创建的任务
    vTaskDelay(100 / portTICK_PERIOD_MS);
    xTaskCreate(xiao_xi_fen_fa, "xiao_xi_fen_fa", 1024 * 2, NULL, 12, NULL);
    // 创建ping任务  
    //xTaskCreate(&ping_task, "ping_task", 4096, NULL, 5, NULL);  
    app_bt_aa(); // 启动蓝牙
    vTaskDelay(100 / portTICK_PERIOD_MS);
    wifi_Start(); // 启动WIFI
    vTaskDelay(100 / portTICK_PERIOD_MS);
    zhong_duan_init();
    /*时间同步*/
    esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("ntp1.aliyun.com");
    esp_netif_sntp_init(&config);
    // uint16_t sj = 0;
    while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) != ESP_OK)
    {
        ESP_LOGI(TAG, "等待系统时间设置... \n");
    }
    set_shi_jian_tong_bu();
    while (1)
    {
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
#if 0
    float zkb = 0;
    for (int i = 10; i >= 0; i--)
    {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS); // 定时器延时  
        gpio_set_level(led_pin, 0);            // 输出低电平
        zkb = zkb + 0.1;

        if (i < 2)
        {
            i = 20;
        }
        if (zkb > 0.9)
        {
            zkb = 0.1;
        }

        vTaskDelay(1000 / portTICK_PERIOD_MS);
        gpio_set_level(led_pin, 1); // 输出高电平
        ESP_LOGI(TAG, "现在的占空比为: %f", zkb);
        ledPwmTianYao(zkb);
    }
    printf("Restarting now.\n");
    fflush(stdout); // 用于刷新标准输出流
    esp_restart();  // 重启
#endif
}




